#include "Timer.h"
#include "ReportError.h"
#include <Windows.h>

Timer::Timer()
{
	m_Dt = 0.0f;
	m_Fps = 0.0f;

	 if(!QueryPerformanceFrequency((LARGE_INTEGER *)&m_TicksPerSecond))   
	 {
        m_TicksPerSecond = 1000; 
	 }

	m_LastFPSUpdate = 0;
	m_NumFrames = 0;
	m_RunningTime = m_Dt = m_Fps = 0.0f;
	m_FPSUpdateInterval = 1.0;
	m_TimerStopped = true;
}

//Starts & Reset the timer
void Timer::Start()
{
	// Get the current time so we know when we started   
    if(!QueryPerformanceCounter((LARGE_INTEGER *)&m_BaseTicks))  
	{
		m_BaseTicks = 0.0;
	}
  

	m_TimerStopped = false;

	m_Dt = 0.0f;
	m_Fps = 0.0f;

	m_LastFPSUpdate = 0;   
    m_NumFrames = 0;  
}

//Stops the timer
void Timer::Stop()
{
	if (!m_TimerStopped)
	{
		// Remember when we stopped so we can know how long we have been paused   
        if(!QueryPerformanceCounter((LARGE_INTEGER *)&m_StopTicks))   
        {   
			ReportError("Could Not Stop Timer");
			m_TimerStopped = false;   
        }   

		else
		{
			m_TimerStopped = true;  
		}
	}
}

// Start the timer without resetting   
void Timer::Continue()   
{   
    if(m_TimerStopped)   
    {   
        UINT64 Ticks;   
        // Get the current time   
        if(!QueryPerformanceCounter((LARGE_INTEGER *)&Ticks) )   
        {   
            //Ticks = (UINT64)timeGetTime(); 
			ReportError("Unable To Continue Timer");
			m_TimerStopped = true;   
        }   

		else
		{
			// Increase baseticks to reflect the time we were paused   
			m_BaseTicks += Ticks - m_StopTicks;   
			m_TimerStopped = false;   
		}
	}   
}  

//Calculates the time elapsed since the last Update call.
//Updates the frames per second and updates the total running time.
void Timer::Update()
{
	UINT64 Ticks;   
   
    if(!m_TimerStopped)   
    {   
        if(!QueryPerformanceCounter((LARGE_INTEGER *)&Ticks))   
        {   
           ReportError("Unable To Update Timer");
        }   
    }   

    else  
	{
        Ticks = m_StopTicks;   
	}
   
    // Subtract the time when we started to get    
    // the time our timer has been running   
    Ticks -= m_BaseTicks;   
   
	//Elapsed Time
    m_RunningTime = (float)(__int64)Ticks/(float)(__int64) m_TicksPerSecond;   

	m_Dt = m_RunningTime - m_FrameTime;   
    m_FrameTime += m_Dt;   
   
    // Update frames per second counter   
	m_NumFrames++; 
	if(m_FrameTime - m_LastFPSUpdate > m_FPSUpdateInterval)   
    { 
		m_Fps = m_NumFrames / (m_RunningTime - m_LastFPSUpdate);
		m_LastFPSUpdate =(__int64)m_FrameTime;
		m_NumFrames = 0;
	}
}

void Timer::Reset()
{
	if(!QueryPerformanceFrequency((LARGE_INTEGER *)& m_TicksPerSecond))
	{
		ReportError("Unable To Restart Timer");
	}

	else
	{
		Start();
	}	
}

float Timer::GetDtTime() 
{
	if(m_TimerStopped)
	{
		return 0.0f;
	}	

	//else if( m_Dt < 0.02f || m_Dt > 0.10f)
	//{
	//	return 0.02f;
	//}

	return m_Dt;
}

//NowNotWorking
void Timer::SetRunningTime(__int64 runningTime)
{
	m_RunningTime = (float)runningTime;
}
